<!--
 * @Description: 轮播通知,(待优化)
 * 目前是使用两段数组进行数据替换操作,循环向左移动.这样数据替换会有一点变化,图片能明显看出来被加载过.
 * 后面可以将第一段数组移动到第二段后面继续动画,这样就不会有加载的变化了
 * @Version: 0.0.1
 * @Autor: zhj1214
 * @Date: 2024-01-25 16:59:39
 * @LastEditors: zhj1214
 * @LastEditTime: 2024-10-16 17:16:13
-->

<template>
  <div
    v-if="props.list.length > 0"
    class="broadcast items-center"
    :class="{
      'broadcast-start': broadcast.restore === 1,
      'animation-none': broadcast.restore === 2,
      'broadcast-nextstart': broadcast.restore === 3,
    }"
    :style="{
      left: broadcast.leftOffset,
    }"
    @animationend="broadcastEnd"
  >
    <!-- 第一段 -->
    <div
      v-for="item in broadcast.startList"
      :key="item"
      class="broadcast-item items-center"
      :style="{
        margin: `0 ${broadcast.margin}px`,
        'min-width': `${broadcast.widthItem}px`,
        'max-width': `${broadcast.widthItem}px`,
      }"
    >
      <!-- <img class="broadcast-item-img" :src="item.avatar" /> -->
      <div class="broadcast-item-img">
        <Images
          :src="item.avatar"
          :placeholder="imgUrl.avatarDefault"
          isHttp
        ></Images>
      </div>

      <div class="broadcast-item-info items-center">
        <span class="broadcast-item-nick" style="margin-right: 6px">
          {{ item.nickname ? item.nickname.substring(0, 11) : "--" }}
          <span style="margin-left: -4px">
            {{ item.nickname && item.nickname.length > 11 ? "..." : "" }}
          </span>
        </span>
        <span class="broadcast-item-nick">{{ $t("lottery.cjtzlb") }}</span>
        <span class="broadcast-item-bdc">{{ item.acquireAmount }}</span>
        <span class="broadcast-item-nick">BDC</span>
      </div>
    </div>
    <!-- 第二段 -->
    <div
      v-for="item in broadcast.endList"
      :key="item"
      class="broadcast-item items-center"
      :style="{
        margin: `0 ${broadcast.margin}px`,
        'min-width': `${broadcast.widthItem}px`,
        'max-width': `${broadcast.widthItem}px`,
      }"
    >
      <!-- <img class="broadcast-item-img" :src="item.avatar" /> -->
      <div class="broadcast-item-img">
        <Images
          :src="item.avatar"
          :placeholder="imgUrl.avatarDefault"
          isHttp
        ></Images>
      </div>
      <div class="broadcast-item-info items-center">
        <div class="broadcast-item-nick" style="margin-right: 6px">
          {{ item.nickname ? item.nickname.substring(0, 11) : "--" }}
          <span style="margin-left: -4px">
            {{ item.nickname && item.nickname.length > 11 ? "..." : "" }}
          </span>
        </div>
        <div class="broadcast-item-nick">{{ $t("lottery.cjtzlb") }}</div>
        <div class="broadcast-item-bdc">{{ item.acquireAmount }}</div>
        <div class="broadcast-item-nick">BDC</div>
      </div>
    </div>
  </div>
</template>
<script setup lang="ts" name="broadcast">
import { useWindowSize } from "@vant/use";
import { ref, reactive, onMounted } from "vue";
import { getOssFileUrl } from "@/utils";

type Item = {
  nickname: string;
  avatar: string;
  acquireAmount: number;
};

const props = withDefaults(
  defineProps<{
    list: any;
    loop?: boolean;
  }>(),
  {
    list: [],
    loop: false,
  }
);
const emit = defineEmits(["end"]);

const imgUrl = getOssFileUrl({
  avatarDefault: "/image/avatar-default.png",
});

// 获取窗口宽度和高度
const { width, height } = process.client
  ? useWindowSize()
  : { width: ref(320), height: ref(667) };

const broadcast = reactive({
  list: [],
  startList: [],
  endList: [],
  endIdx: 0, // 3 也是组件最小长度
  pace: 3,
  leftOffset: "0px",
  widthItem: 225, // 每一个信息的宽度
  widthItemPX: "-225px", // 每一个信息的宽度
  animation: "",
  margin: 10, // 两个 item 的左右间距
  marginPx: "10px", // 两个 item 的左右间距
  restore: 1, // 1. 第一种动画速度 2.none 3. 第二种动画速度
});

// 一次动画结束:展示了两段数据
const broadcastEnd = () => {
  broadcast.restore = 2;
  // 1. 将第二段数据赋值给第一段,重置偏移量
  broadcast.startList = broadcast.list.slice(
    broadcast.endIdx,
    broadcast.endIdx + broadcast.pace
  );
  broadcast.leftOffset = `-${
    broadcast.widthItem * broadcast.pace +
    broadcast.margin * (broadcast.pace - 2) -
    width.value
  }px`;

  // 2. 重新计算 endIdx
  broadcast.endIdx = broadcast.endIdx + broadcast.pace;
  // 3. 重新赋值
  broadcast.endList = broadcast.list.slice(
    broadcast.endIdx,
    broadcast.endIdx + broadcast.pace
  );
  setTimeout(() => {
    broadcast.restore = 3;
  }, 0);
  // 4. 整个动画结束的通知 broadcast.pace + 1 代表一段的长度
  if (broadcast.endIdx >= broadcast.list.length - broadcast.pace) {
    // console.log("--最后一次---", broadcast.endIdx);
    if (props.loop) {
      broadcast.endIdx = 0;
    } else {
      emit("end");
    }
  }
};
onMounted(() => {
  // mock 数据
  if (props.list.length % 3 !== 0) {
    broadcast.list = props.list.concat(props.list).concat(props.list);
  } else {
    broadcast.list = props.list;
  }

  // 初始值,默认broadcast.pace 个数一段,可以自定义,当前是 3 个一段
  broadcast.endIdx = broadcast.pace;
  broadcast.animation = `leftCarousel ${broadcast.pace * 2 * 5}s linear 1`; // 2 代表两段 5 代表速度
  // 截取第一段
  broadcast.startList = broadcast.list.slice(0, broadcast.endIdx);
  // 截取第二段
  broadcast.endList = broadcast.list.slice(
    broadcast.endIdx,
    broadcast.endIdx + broadcast.pace
  );
});
</script>
<style scoped lang="scss">
.broadcast {
  @keyframes leftCarousel {
    0% {
      left: v-bind("broadcast.leftOffset");
    }
    100% {
      left: calc(
        v-bind("broadcast.pace") * 2 * v-bind("broadcast.widthItemPX") -
          (v-bind("broadcast.marginPx") * (v-bind("broadcast.pace") * 2 + 1)) +
          100vw
      );
    }
  }
  position: relative;
  min-width: 100vw;

  &-start {
    // animation: v-bind("broadcast.animation");
    animation: leftCarousel 12s linear 1;
    // animation-fill-mode: forwards;
  }
  &-nextstart {
    animation: leftCarousel 9s linear 1 !important;
  }
  &-item {
    align-items: flex-end;
    &-img {
      overflow: hidden;
      min-width: 24 * 2px !important;
      max-width: 24 * 2px !important;
      height: 24 * 2px;
      border-radius: 100px;
      border: 1px solid #007bff;
    }
    &-info {
      z-index: -1;
      height: 18 * 2px;
      position: relative;
      left: -24px;
      padding-left: 32px;
      background: linear-gradient(
        90deg,
        rgba(0, 123, 255, 0.6) 0%,
        rgba(0, 123, 255, 0) 100%
      );
    }
    &-nick {
      color: #002853;
      font-size: 11 * 2px;
      text-wrap: nowrap;
      white-space: nowrap;
    }
    &-bdc {
      margin: 0 4 * 2px;
      color: #ffb800;
      font-size: 11 * 2px;
      font-weight: 590;
    }
  }
}
.animation-none {
  animation: none;
}
</style>
